﻿using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using Caliburn.Micro;
using PocketBook.Model;
using PocketBook.Properties;
using PocketBook.Tasks;

namespace PocketBook.ViewModels
{
    [Export(typeof(IShell))]
    public sealed class MainViewModel : Screen, IShell
    {
        private const string FileExtension = ".pbk";
        private const string Filter = "Pocket Books|*" + FileExtension;

        private string _fileName;
        private bool _isDirty;

        public MainViewModel()
        {
            DisplayName = Resources.Caption_Application;
        }

        public bool IsDirty
        {
            get { return _isDirty; }
            set
            {
                if (value == IsDirty) return;

                _isDirty = value;
                NotifyOfPropertyChange(() => IsDirty);
            }
        }

        public string FileName
        {
            get { return _fileName; }
            set
            {
                if (value == FileName) return;

                _fileName = value;
                DisplayName = String.Format(String.IsNullOrWhiteSpace(FileName) ? "{0}" : "{1} - {0}", Resources.Caption_Application, Path.GetFileName(FileName));

                NotifyOfPropertyChange(() => CanSaveBookAs);
            }
        }

        [Import(typeof(IBookDesigner))]
        public IBookDesigner BookLayout
        {
            get;
            set;
        }

        [Import(typeof(DesignCatalogViewModel))]
        public object DesignCatalog
        {
            get; set;
        }

        [Import(typeof(EditorViewModel))]
        public object DesignEditor
        {
            get;
            set;
        }

        [Import]
        private IPrintService PrintService
        {
            get;
            set;
        }

        public void NewBook()
        {
            BookLayout = IoC.Get<IBookDesigner>();
            NotifyOfPropertyChange(() => BookLayout);

            FileName = null;
            IsDirty = false;
        }

        public IEnumerable<IResult> OpenBook()
        {
            var selectFile = Show.OpenFileDialog();
            selectFile.Filter = Filter;
            selectFile.DefaultExtension = FileExtension;
            selectFile.CheckIfFileExists = true;

            yield return selectFile;

            var loadBook = new DeserializationTask<Book> { FileName = selectFile.FileName };
            yield return loadBook;

            BookLayout.Book = loadBook.Result;

            FileName = selectFile.FileName;
            IsDirty = false;
        }

        public IEnumerable<IResult> SaveBook()
        {
            return Save(FileName);
        }

        public bool CanSaveBookAs
        {
            get { return ! String.IsNullOrEmpty(FileName); }
        }

        public IEnumerable<IResult> SaveBookAs()
        {
            return Save(null);
        }

        public void PrintBook()
        {
            PrintService.Print(Book);
        }

        public void PrintPreview()
        {
            PrintService.ShowPrintPreviewOf(Book);
        }

        public void Exit()
        {
            TryClose();
        }

        private Book Book
        {
            get { return BookLayout.Book; }
        }

        private IEnumerable<IResult> Save(string fileName)
        {
            if (String.IsNullOrEmpty(fileName))
            {
                var selectFile = Show.SaveFileDialog();
                selectFile.Filter = Filter;
                selectFile.DefaultExtension = FileExtension;

                if (!String.IsNullOrWhiteSpace(FileName))
                {
                    selectFile.InitialDirectory = Path.GetDirectoryName(FileName);
                    selectFile.FileName = Path.GetFileName(FileName);
                }

                yield return selectFile;

                FileName = selectFile.FileName;
            }

            yield return new SerializationTask<Book>
            {
                FileName = fileName,
                Source = Book
            };

            IsDirty = false;
        }
    }
}
